Описание: blank

Описание: blank

127018, Москва, улущевский Вал д.18
Тел./факс:
+7 (495) 780 4820
+7 (495) 660 2330
сайт: http://www.cryptopro.ru
e-mail: info@cryptopro.ru

Описание: Крипто-Про

Описание: blank

Описание: blank

 

Программный
Комплекс
Защиты
Информации

КриптоПро JTLS
Версия

 

 

Руководство программиста КриптоПро JTLS

 

© OOO "Крипто-Про", 2005-2013. Все права защищены.

Авторские права на программный комплекс защиты информации КриптоПро JTLS и эксплуатационную документацию зарегистрированы в Российском агентстве по патентам и товарным знакам (Роспатент).

Документ входит в комплект поставки программного обеспечения КриптоПро JTLS, и на него распространяются все условия лицензионного соглашения. Без специального письменного разрешения OOO "Крипто-Про" документ или его часть в электронном или печатном виде не могут быть скопированы и переданы третьим лицам с коммерческой целью.

Описание: blank

Описание основной функциональности криптопровайдера КриптоПро JCP

Описание основной функциональности криптопровайдера КриптоПро JCP (модули шифрования)

Связь с разработчиком.
Поддержка.
Форум.




Содержание

  1. Введение
  2. Установка КриптоПро JTLS
  3. Работа через внешний интерфейс JSSE
  4. Управление ключами и сертификатами
  5. Реализуемые шифр-сюиты и совместимость по ним с различными версиями КриптоПро CSP
  6. Контрольная панель
  7. Использование КриптоПро JTLS в Apache Tomcat
  8. Отладка
  9. Криптопровайдер JCSP. Особенности

Введение

КриптоПро JTLS является программным комплексом защиты информации, разработанным на основе КриптоПро JCP и реализующим протоколы SSL и TLS в соответствии с российскими криптографическими алгоритмами.

Основные функции, реализуемые КриптоПро JTLS:

В случае аутентификации клиента на ключе подписи применяются алгоритмы выработки электронной подписи в соответствии с ГОСТ Р 34.10-2001 и проверки в соответствии с ГОСТ Р 34.10-2001.

Установка КриптоПро JTLS

Предварительно установить КриптоПро JCP (включая модули шифрования). Далее установку можно выполнить двумя путями:

Использование КриптоПро JTLS возможно только на Java 1.6 и выше. Для преодоления экспортных ограничений на стойкую криптографию см. Особенности подключения КриптоПро JTLS.

Работа через внешний интерфейс JSSE

ПКЗИ КриптоПро JTLS реализует стандартный интерфейс Java Secure Socket Extension (JSSE) v.1.6 и обеспечивает выполнение защищенной передачи данных по протоколам SSL и TLS в соответствии с российскими криптографическими алгоритмами через стандартный интерфейс JSSE.

Особенности подключения КриптоПро JTLS

Из-за того, что обычно в JSSE, помимо самого интерфейса, включаются и некоторые его реализации (примером такой реализации на SUNовской виртуальной машине является провайдер com.sun.net.ssl.internal.ssl.Provider), существуют некоторые особенности использования ПКЗИ КриптоПро JTLS.

Возможна ситуация, когда установленная JRE имеет экспортные ограничения. США запрещает экспорт "сильной" криптографии и JCP с длиной ключа 256 бит попадает под это ограничение. Ограничения устанавливаются файлами local_policy.jar и US_export_policy.jar в каталоге <JRE>/jre/lib/security. Для снятия экспортных ограничений необходимо скачать файл jce_policy-6.zip с политиками со страницы http://java.sun.com/javase/downloads/index.jsp , выбирая "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6". Для отладки же можно просто скопировать US_export_policy.jar в local_policy.jar (оба файла должны присутствовать).

Использование КриптоПро JTLS через внешний интерфейс JSSE

После того, как КриптоПро JTLS подключен, дальнейшая работа с протоколами SSL и TLS в соответствии с российскими криптографическими алгоритмами осуществляется через стандартный интерфейс JSSE, например, при помощи метода getDefault() классов SSLServerSocketFactory и SSLSocketFactory.

·          
·             // порт, по которому данный сервер устанавливает соединение
·             int port;
·          
·             SSLServerSocketFactory sslSrvFact =
·                     (SSLServerSocketFactory) SSLServerSocketFactory
·                                 .getDefault();
·             SSLServerSocket ss = (SSLServerSocket)sslSrvFact.createServerSocket(port);

Защищенное соединение в общем случае может быть осуществлено и при помощи класса ServerSocket (объекты именно этого класса возвращаются методом createServerSocket(port)). Однако, такой класс имеет меньшую функциональность, чем его расширение - класс SSLServerSocket. Выбор того, каким классом пользоваться, базируется на необходимости установления тех или иных атрибутов процесса обмена.

·          
·             // порт сервера, по которому устанавливается соединение
·             int port;
·          
·             // имя хоста сервера, по которому устанавливается соединение
·             String host;
·          
·             SSLSocketFactory sslFact =
·                 (SSLSocketFactory) SSLSocketFactory.getDefault();
·             SSLSocket soc = (SSLSocket)sslFact.createSocket(host, port);

Защищенное соединение в общем случае может быть осуществлено и при помощи класса Socket (объекты именно этого класса возвращаются методом createSocket(host, port)). Однако, такой класс имеет меньшую функциональность, чем его расширение - класс SSLSocket. Выбор того, каким классом пользоваться, базируется на необходимости установления тех или иных атрибутов процесса обмена.

Примеры создания защищенного соединения между клиентом и сервером по протоколу TLS приводятся в Samples/JTLS_samples, входящих в пакет поставки КриптоПро JCP. Пакет ComLine модуля Samples содержит примеры сервера и клиента, запускаемые из командной строки.

Управление ключами и сертификатами

В ПКЗИ КриптоПро JTLS в процессе установления защищенного соединения по протоколам SSL и TLS используются следующие три типа объектов:

В зависимости от роли данной стороны (клиент или сервер), а также от типа аутентификации (односторонняя или двусторонняя) существуют особенности использования данных объектов.

Управление ключами и сертификатами сервером

Общие положения

В ПКЗИ КриптоПро JTLS аутентификация может быть односторонней или двусторонней (т.е. сервер ВСЕГДА отправляет свой сертификат аутентификации клиенту). Поэтому, если данная сторона является сервером, то необходимо, чтобы у нее существовали закрытый ключ и соответствующий ему сертификат (цепочка сертификатов) аутентификации, в соответствии с которыми и будет устанавливаться защищенное соединение. Причем, допустимы к использованию только следующие пары (закрытый ключ обмена и соответствующий ему сертификат аутентификации):

Действия перед началом обмена с клиентом

Таким образом, перед началом осуществления соединения с клиентом, такие закрытый ключ и соответствующий ему сертификат (цепочка сертфикат) необходимо создать и затем положить в ключевое хранилище, из которого они и будут прочитаны в процессе обмена. Методы выполнения этих операций подробно описаны в руководстве программиста КриптоПро JCP, а также в руководство программиста (модули шифрования). Ниже приводятся примеры таких методов.

Создание закрытого ключа обмена и соответствующего ему открытого ключа осуществляется при помощи методов стандартного класса KeyPairGenerator, проинициализированного именем "GOST3410DH" (это имя соответствует алгоритмам обмена Диффи-Хэллмана и подписи ГОСТ 34.10-2001):

 
    KeyPairGenerator kg = KeyPairGenerator.getInstance("GOST3410DH");
    KeyPair pair = kg.generateKeyPair();
    // закрытый ключ обмена
    PrivateKey privKey = pair.getPrivate();
    // соответствующий ему открытый ключ
    PublicKey pubKey = pair.getPublic();

Создание сертификата аутентификации при помощи методов класса GostCertificateRequest, представляющего собой дополнительную возможность работы с сертификатами, реализованную на базе СКЗИ КриптоПро JCP (подробное описание смотри в соответствующем разделе):

 
    String keyAlg = "GOST3410DH";
    String certName = "CN=newCert, O=CryptoPro, C=RU";
    String httpAddress = "http://www.cryptopro.ru/certsrv/";
 
    // создание запроса на сертификат аутентификации сервера 
    GostCertificateRequest request = new GostCertificateRequest();
    request.setKeyUsage(GostCertificateRequest.CRYPT_DEFAULT);
    request.addExtKeyUsage(GostCertificateRequest.INTS_PKIX_CLIENT_AUTH);
    request.addExtKeyUsage(GostCertificateRequest.INTS_PKIX_SERVER_AUTH);
    request.setPublicKeyInfo(pubKey);
    request.setSubjectInfo(certName);
    request.encodeAndSign(privKey);
 
    // отправка запроса центру сертификации и получение от центра
    // сертификата в DER-кодировке
    byte[] encoded = request.getEncodedCert(httpAddress);
 
    // генерация X509-сертификата из закодированного представления сертификата
    CertificateFactory cf = CertificateFactory.getInstance("X509");
    java.security.cert.Certificate cert = cf.generateCertificate(new ByteArrayInputStream(encoded));

Запись созданного закрытого ключа и цепочки сертификатов, состоящей из сертификата аутентификации и корневого сертификата центра сертификации, на жесткий диск (более подробно о типах ключевых хранилищ, реализованных в КриптоПро JCP, и особенностях их использования, читай в соответствующем разделе ):

 
    String password = "password";      
    String alias = "newKey";      
    String certPath = "C:\\certificate.cer"; // файл, в который был предварительно
                                             // сохранен корневой сертификат центра
 
 
    CertificateFactory cf = CertificateFactory.getInstance("X509"); 
    FileInputStream fis = new FileInputStream(certPath); 
    java.security.cert.Certificate certRoot = cf.generateCertificate(new BufferedInputStream(fis)); 
 
    java.security.cert.Certificate[] certs = new java.security.cert.Certificate[2];
    certs[0] = certRoot;    
    certs[1] = cert;    
 
    KeyStore hdImageStore = KeyStore.getInstance("HDImageStore");
    hdImageStore.load(null, null);
    hdImageStore.setKeyEntry(alias, privKey, password.toCharArray(), certs);
    hdImageStore.store(null, null);

В данных примерах приводилось использование тестового центра сертификации КриптоПро. Получение корневого сертификата этого центра может быть осуществлено по следующей ссылке. Для рабочих целей (при обращении к центру сертификации КриптоПро УЦ) получение корневого сертификата осуществляется по следующей ссылке.

Также можно воспользоваться готовыми классами пакета ComLine из модуля Samples, входящего в состав КриптоПро JCP. Запустите ComLine с вызовом нужного класса либо сам класс, используя следующие параметры командной строки:

java ComLine NameofClass args или java NameofClass args

например:

 
java ComLine KeyPairGen -alias name_of_key -dname CN=autor,OU=Security,O=CryptoPro,C=RU -reqCertpath C:/req.txt

или

 
java KeyPairGen -alias name_of_key -dname CN=autor,OU=Security,O=CryptoPro,C=RU -reqCertpath C:/req.txt

Генерирование ключевой пары (в соответствие алгоритмам обмена Диффи-Хелмана и подписи ГОСТ Р 34.10-2001) и соответствующего ей самоподписанного сертификата. Запись их на носитель. Генерация запроса (DER) на сертификат и запись его в файл.

Получение сертификата из запроса, представленного в DER-кодировке и запись его в хранилище и в файл.

Построение цепочки сертификатов.

Работа с ключами обмена и сертификатами аутентификации

Сам процесс обмена начинается с того, что определяется, какая именно пара (закрытый ключ обмена - сертификат аутентификации сервера) будет использован. Для этого пользователю, выполняющему роль сервера, необходимо указать, из какого ключевого хранилища будет прочитана требуемая пара. Указывается это при помощи системных настроек следующим образом:

 
    System.setProperty("javax.net.ssl.keyStoreType","HDImageStore"); 
    System.setProperty("javax.net.ssl.keyStorePassword","password"); 

Настройка "javax.net.ssl.keyStoreType" задает тип ключевого носителя, с которого будет прочитан закрытый ключ и соответствующий ему сертификат аутентификации (цепочка сертификатов). Таким образом, в качестве типа носителя нужно указывать тот носитель, на который предварительно была записана требуемая пара. Если такую настройку не производить, то по умолчанию в качестве носителя будет использован жесткий диск ("HDImageStore").

Настройка "javax.net.ssl.keyStorePassword" определяет пароль на закрытый ключ обмена. Таким образом, в качестве пароля нужно указывать тот пароль, с которым на носитель была записана требуемая ключевая пара. Если такую настройку не производить, то по умолчанию будет использоваться нулевой пароль.

Таким образом, с заданного носителя "javax.net.ssl.keyStoreType" будут прочитаны все хранящиеся на нем закрытые ключи и сертификаты (цепочки сертификатов), удовлетворяющие паролю "javax.net.ssl.keyStorePassword" и требованиям:

В качестве рабочей пары будет выбрана первая.

Работа с доверенными сертификатами

В случае двусторонней аутентификации, клиент присылает серверу свой сертификат аутентификации. Сервер при этом должен проверить, что сертификату клиента можно доверять. Для этих целей в ПКЗИ КриптоПро JTLS используется так называемое множество доверенных сертификатов, которое определяется при помощи следующих системных настроек:

 
    System.setProperty("javax.net.ssl.trustStoreType","HDImageStore"); 
    System.setProperty("javax.net.ssl.trustStore","C:\\Java\\jcp\\trust"); 
    System.setProperty("javax.net.ssl.trustStorePassword","password"); 

Настройка "javax.net.ssl.trustStoreType" определяет тип хранилища сертификатов. Как описано в соответствующем разделе, в КриптоПро JCP хранилище сертификатов, как правило, ассоциируется с некоторым ключевым носителем (при этом тип хранилища сертификатов совпадает с типом ключевого носителя). Таким образом, если в данной настройке в качестве типа хранилища указывает тип ключевого носителя, то с указанного носителя будут прочитаны все корневые сертификаты цепочек и эти сертификаты будут добавлены во множество доверенных сертификатов (если цепочка состоит из одного сертификата, то этот сертификат также будет считаться доверенным). Если такую настройку не производить, то по умолчанию в качестве типа хранилища сертификатов будет использован жесткий диск ("HDImageStore")

Настройка "javax.net.ssl.trustStore" задает путь к хранилищу сертификатов, соответствующему типу "javax.net.ssl.trustStoreType". Такое хранилище используется в том случае, когда сертификат клиента подписан некоторым центром сертификации, корневой сертификат которого не участвует ни в одной цепочке, прочитанной с носителя "javax.net.ssl.trustStoreType", однако серверу известно, что такому центру сертификации можно доверять. Для этого, серверу предварительно необходимо положить корневой сертификат этого центра в хранилище сертификатов "javax.net.ssl.trustStore" следующим образом:

 
    String certPath = "C:\\certificate.cer";    // файл, в который был предварительно
                                                // сохранен корневой сертификат центра
 
 
    KeyStore ks = KeyStore.getInstance("HDImageStore"); 
    ks.load(null, null); 
    CertificateFactory cf = CertificateFactory.getInstance("X509"); 
    
    FileInputStream fis = new FileInputStream(certPath); 
    java.security.cert.Certificate cert = cf.generateCertificate(new BufferedInputStream(fis)); 
    ks.setCertificateEntry("certificate", cert); 
        
    FileOutputStream fos = null; 
    fos = new FileOutputStream("C:\\Java\\jcp\\trust"); 
    ks.store(fos, "password".toCharArray()); 
    fos.close(); 

Из указанного хранилища сертификатов будут прочитаны все сертификаты, и они также будут добавлены во множество доверенных сертификатов. Если данную настройку не производить, то по умолчанию хранилище сертификатов использоваться не будет (в качестве доверенных будут использоваться только корневые сертификаты цепочек, прочитанных с носителя"javax.net.ssl.trustStoreType").

Настройка "javax.net.ssl.trustStorePassword" определяет пароль на доступ к хранилищу сертификатов (пароль, с которым это хранилище было сохранено). Если такую настройку не производить, то пароль считается нулевым.

Повторим, что определенное таким образом множество доверенных сертификатов сервером используется только в случае двусторонней аутентификации (т.е. в этом случае оно не должно быть пустым). В случае двусторонней аутентификации сервер отравляет клиенту список имен издателей, которым он доверяет. Этот список формируется из имен субъектов всех доверенных сертификатов.

При получении сертификата аутентификации (цепочки сертификатов) от клиента, он считается успешно проверенным в одном из четырех случаев:

Управление ключами и сертификатами клиентом

Общие положения

С точки зрения роли клиента основное различие в управлении ключами проводится для эфемерального и неэфемерального обмена. Неэфемеральный обмен в ПКЗИ КриптоПро JTLS допустим только для ключей обмена, соответствующих алгоритмам обмена Диффи-Хэллмана и подписи ГОСТ 34.10-2001. Во всех остальных случаях, эфемеральный обмен производится на ключах, соответствующих алгоритму ГОСТ 34.10-2001.

Напомним, что эфемеральный обмен осуществляется в двух случаях:

Как следует из описанного выше, в случае двусторонней аутентификации, если данная сторона является клиентом, необходимо чтобы у нее существовали закрытый ключ и соответствующий ему сертификат (цепочка сертификатов) аутентификации. Причем, допустимы к использованию только следующие пары (закрытый ключ обмена и соответствующий ему сертификат аутентификации):

Действия перед началом обмена с сервером

Таким образом, перед началом осуществления соединения с сервером в случае двусторонней аутентификации, такие закрытый ключ и соответствующий ему сертификат (цепочку сертификатов) необходимо создать и затем положить в ключевое хранилище, из которого они и будут прочитаны в процессе обмена. Осуществление таких действий производится аналогично описанию для сервера. Единственная разница состоит в том, что создаваемый сертификат аутентификации имеет расширения сертификата аутентификации клиента. Создание таких сертификатов производится по следующей схеме:

 
 
    String keyAlg = "GOST3410DH";
    String certName = "CN=newCert, O=CryptoPro, C=RU";
    String httpAddress = "http://www.cryptopro.ru/certsrv/";
 
    // создание запроса на сертификат аутентификации сервера 
    GostCertificateRequest request = new GostCertificateRequest();
    request.setKeyUsage(GostCertificateRequest.CRYPT_DEFAULT);
    request.addExtKeyUsage(GostCertificateRequest.INTS_PKIX_CLIENT_AUTH);
    request.setPublicKeyInfo(pubKey);
    request.encodeAndSign(privKey);
 
    // отправка запроса центру сертификации и получение от центра
    // сертификата в DER-кодировке
    byte[] encoded = request.getEncodedCert(httpAddress);
 
    // генерация X509-сертификата из закодированного представления сертификата
    CertificateFactory cf = CertificateFactory.getInstance("X509");
    java.security.cert.Certificate cert = cf.generateCertificate(new ByteArrayInputStream(encoded));

Работа с ключами обмена и сертификатами аутентификации

Эта работа осуществляет только в случае двусторонней аутентификации и аналогична описанию для сервера. Единственная разница состоит в выборе пары (закрытый ключ обмена - сертификат аутентификации). Если в случае сервера, в качестве рабочей пары выбирается первая подходящая пара, прочитанная с ключевого носителя, то в данном случае возможны два варианта:

Работа с доверенными сертификатами

Поскольку считается, что сервер ВСЕГДА присылает свой сертификат клиенту, то проверка сертификата клиентом осуществляется всегда. Она основывается на множестве доверенных сертификатов клиента, формируемого и используемого аналогично описанию сервера. Очевидно, что это множество должно быть не пустым.

Реализуемые шифр-сюиты и совместимость по ним с различными версиями КриптоПро CSP

Описание реализуемых КриптоПро JTLS шифр-сюит

ПКЗИ КриптоПро JTLS реализует три варианта шифр-сюит. В реализованных шифр-сюитах используются следующие алгоритмы:

Ниже приводится таблица с кратким описанием реализуемых КриптоПро JTLS шифр-сюит:

Имя шифр-сюиты

Идентификатор шифр-сюиты

Алгоритм ключей обмена

Режим шифрования данных по алгоритму ГОСТ Р 28147-89

TLS_CIPHER_2001

0x81

ГОСТ 34.10-2001

Гаммирование

SSL3_CK_GVO_KB2

0x32

ГОСТ 34.10-2001

Гаммирование с обратной связью

SSL3_CK_GVO

0x31

ГОСТ 34.10-2001

Гаммирование с обратной связью

В данной таблице шифр-сюиты перечислены в порядке уменьшения приоритета. Соответственно, при получении от клиента списка шифр-сюит, сервер выбирает подходящую шифр-сюиту с наибольшим приоритетом.

Поддержка шифр-сюит клиентом и сервером в КриптоПро JTLS

При инициализации процесса обмена, текущая сторона формирует список поддерживаемых шифр-сюит. Этот список будет различаться в зависимости от того, является текущая сторона клиентом или сервером. Поддерживаемые шифр-сюиты заносятся в список в соответствии с порядком их приоритета (первой заносится шифр-сюита с наибольшим приоритетом). Дальнейший процесс обмена текущей стороной будет осуществляться в соответствии с сформированным списком. Отправка клиентом списка серверу осуществляется именно в таком виде, в каком он был сформирован (в порядке уменьшения приоритета). Разбор полученного от клиента списка сервером также осуществляется в порядке уменьшения приоритета.

Таким образом, формируются следующие списки поддерживаемых шифр-сюит:

Клиент

Сервер

TLS_CIPHER_2001

TLS_CIPHER_2001

SSL3_CK_GVO_KB2

SSL3_CK_GVO_KB2

SSL3_CK_GVO (опционально)

SSL3_CK_GVO

Совместимость по шифр-сюитам с различными версиями КриптоПро CSP

Ниже приводится таблица, в которой описывается, какая именно шифр-сюита будет выбрана сервером при условии при осуществлении процесса обмена с различными версиями КриптоПро JTLS.

Клиент

Сервер

Выбираемая сервером шифр-сюита

JTLS

JTLS

TLS_CIPHER_2001

JTLS

CSP 2.0

SSL3_CK_GVO_KB2

JTLS

CSP 3.0

TLS_CIPHER_2001

CSP 2.0

JTLS

SSL3_CK_GVO

CSP 3.0

JTLS

TLS_CIPHER_2001

Контрольная панель

Основной набор закладок контрольной панели КриптоПро JCP описан в Руководстве администратора. После установки модуля КриптоПро JTLS на контрольной панели появятся соответствующие закладки.

Закладка "Сервер JTLS"

Описание: Сервер JTLS

Данная панель содержит информацию о серверной лицензии КриптоПро JTLS. Работа с данной панелью аналогична работе с закладкой "Общие" (панель "Лицензия").

Закладка "Настройки сервера"

Описание: Настройки сервера

Данная панель содержит настройки сервера:

Использование КриптоПро JTLS в Apache Tomcat

Основы использования SSL/TLS в читайте в Apache Tomcat SSL Configuration HOW-TO.

Apache Tomcat имеет собственный интерфейс для встраивания SSL/TLS протоколов. Для поддержки существующих интерфейсов и реализаций SSL/TLS, таких как PureTLS и JSSE, в нём используются наборы классов-переходников. Для встраивания КриптоПро JTLS в Apache Tomcat можно воспользоваться

Переходник КриптоПро TomCatSSL использует Sun JSSE, но позволяет применять стойкие криптографические алгоритмы (с ключами большой длины). Встроенный переходник не позволяет делать этого напрямую, если в реализации JSSE заложены экспортные ограничения, как, например, это сделано в Sun JSSE.

Настройка Apache Tomcat проводится в следующем порядке:

  1. Установка КриптоПро JTLS, как указано выше.
  2. Создание сертификата "Проверки подлинности сервера".
  3. Настройка коннектора Apache Tomcat.

Важным обстоятельством является тот факт, что если включена проверка цепочки сертификатов на отзыв по CRLDP сертификата, то необходимо разрешить загрузку СОС, задав параметры

System.setProperty("com.sun.security.enableCRLDP", "true");

либо

System.setProperty("com.ibm.security.enableCRLDP", "true");

Создание сертификата Apache Tomcat

Сертификат выпускается, как указано выше или в руководстве программиста. Его общее имя (common name) должно совпадать с DNS-именем (или IP - при обращении клиентов только по IP) сервера Apache Tomcat. Apache Tomcat перебирает все сертификаты пользователя, под учетной записью которого он работает, пока не найдет подходящий (по назначению и паролю), поэтому необходимо обеспечить его уникальность именно в этом смысле.

По умолчанию (в Windows) Apache Tomcat ищет контейнер с сертификатом под учетной записью системы (даже если в настройках Apache Tomcat указать свойство LogOn под пользовательской учетной записью, поиск подходящего контейнера он все равно ведет в этой папке) поэтому следует либо создать его под учетной записью системы, либо вручную переложить созданный под своей учетной записью контейнер из

%USERPROFILE%\Local Settings\Application Data\Crypto Pro\

в

%USERPROFILE%\..\Default User\Local Settings\Application Data\Crypto Pro\,

либо настроить Apache Tomcat под свою учетную запись следующим образом:

Панель управления -> Администрирование -> Службы и приложения -> Службы -> Apache Tomcat свойства -> вход в систему: с учетной записью (указать имя и пароль).

Настройка коннектора Apache Tomcat

Для настройки коннектора Apache Tomcat необходимо добавить в файл <CATALINA_HOME>/conf/server.xml строки по следующему образцу:

 
     <Connector port="8443" maxHttpHeaderSize="8192"
                protocol="org.apache.coyote.http11.Http11NioProtocol"  
                SSLEnabled="true"
                maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                enableLookups="false" disableUploadTimeout="true"
                acceptCount="100" scheme="https" secure="true"
                clientAuth="false"
                sslProtocol="GostTLS" 
                algorithm="GostX509"
                keystoreProvider="JCP"
                keystoreFile="<USER_HOME>/.keystore"
                keystorePass="11111111"
                keystoreType="HDImageStore"
                keyalg="GOST3410"
                sigalg="GOST3411withGOST3410EL"
                
     />

Описание основных параметров смотрите в документации на Apache Tomcat. В keystoreFile указывается путь к соответствующему файлу. В keystorePass - пароль на контейнер. При указанном выше описании используется встроенный переходник для JSSE.

Важно отметить, что для Apache Tomcat версии 7.0.42 и выше может потребоваться указание дополнительных параметров:

    ciphers="TLS_CIPHER_2001"
    sslEnabledProtocols="GostTLS"

Tomcat может использовать библиотеки Apache Portable Runtime (APR) для повышения производительности. APR использует платформо-зависимую реализацию SSL, которая не может работать с российскими ГОСТ алгоритмами и Java настройками типа keystoreFile и выдаст ошибку. Для предотвращения автоконфигурации через APR и задания Java коннектора, независимо от того загружены ARP библиотеки или нет, необходимо в описании коннектора явно задать имя класса реализации в атрибуте протокола protocol="org.apache.coyote.http11.Http11NioProtocol".

При аутентификации клиента (clientAuth="true") следует также указать путь к хранилищу сертификатов (truststoreFile="<USER_HOME>/.keystore") и пароль (truststorePass="1111111".)

Если используется переходник КриптоПро TomCatSSL, то необходимо скопировать TomCatSSL.jar в <CATALINA_HOME>/server/lib/ (или <CATALINA_HOME>/lib/) и добавить в описание коннектора строку:

    SSLImplementation="ru.CryptoPro.TomCatSSL.JSSEImplementation"

Настройка журналирования КриптоПро JTLS в Apache Tomcat

Для настройки журналирования действий КриптоПро JTLS в файле <CATALINA_HOME>/conf/logging.properties необходимо:

Cоответсвующие изменения помечены жирным шрифтом:

 
 
handlers = 1catalina.org.apache.juli.FileHandler, 2localhost.org.apache.juli.FileHandler, 3manager.org.apache.juli.FileHandler, 4admin.org.apache.juli.FileHandler, 5host-manager.org.apache.juli.FileHandler, 6jtls.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
 
.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
 
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
 
1catalina.org.apache.juli.FileHandler.level = FINE
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.
 
2localhost.org.apache.juli.FileHandler.level = FINE
2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.FileHandler.prefix = localhost.
 
3manager.org.apache.juli.FileHandler.level = FINE
3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
3manager.org.apache.juli.FileHandler.prefix = manager.
 
4admin.org.apache.juli.FileHandler.level = FINE
4admin.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
4admin.org.apache.juli.FileHandler.prefix = admin.
 
5host-manager.org.apache.juli.FileHandler.level = FINE
5host-manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
5host-manager.org.apache.juli.FileHandler.prefix = host-manager.
 
6jtls.org.apache.juli.FileHandler.level = FINE 
6jtls.org.apache.juli.FileHandler.directory = ${catalina.base}/logs 
6jtls.org.apache.juli.FileHandler.prefix = jtls.
 
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
 
 
############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################
 
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.FileHandler
 
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.FileHandler
 
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/admin].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/admin].handlers = 4admin.org.apache.juli.FileHandler
 
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 5host-manager.org.apache.juli.FileHandler
 
ru.CryptoPro.ssl.SSLLogger.level = FINE 
ru.CryptoPro.ssl.SSLLogger.handlers = 6jtls.org.apache.juli.FileHandler
 
# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
#org.apache.catalina.startup.ContextConfig.level = FINE
#org.apache.catalina.startup.HostConfig.level = FINE
#org.apache.catalina.session.ManagerBase.level = FINE
 

Отладка

Для отладки ssl соединения можно воспользоваться встроенным логгером.
Для этого установите уровень FINE в jre/lib/logging.properties:

 
    .level = FINE
    ...
    java.util.logging.ConsoleHandler.level = FINE

SSLLogger является расширением стандартного класса Logger (см. документацию java).

Криптопровайдер JCSP. Особенности

В дистрибутив JCP входит библиотека JCSP.jar. JCSP - провайдер, аналогичный JCP, но осуществляющий все криптографические операции путем обращения в КриптоПро CSP. Криптопровайдер КриптоПро JCSP реализует стандартный интерфейс Java Cryptography Architecture (JCA) в соответствии с российскими криптографическими алгоритмами и в соответствии с этим интерфейсом обеспечивает выполнение тех же операций, что и JCP.

Для указания имени провайдера вместо JCP.PROVIDER_NAME следует использовать JCSP.PROVIDER_NAME. Для того, чтобы использовать установленный провайдер JCSP в cpSSL вместо JCP и Crypto, перед выполнением кода следует записать следующую команду:

    cpSSLConfig.setDefaultSSLProvider(JCSP.PROVIDER_NAME); // класс cpSSLConfig входит в пакет ru.CryptoPro.ssl.util
 
    либо
 
    System.setProperty("ru.CryptoPro.defaultSSLProv", "JCSP");
 

Загрузка одного экземпляра ключевого контейнера с помощью класса StoreInputStream

По умолчанию менеджер ключей модуля cpSSL осуществляет подбор ключевых контйнеров простым перечислением их с помощью метода aliases() класса KeyStore и применением к ним некоторого пароля, который может быть передан как при создании объекта SSLContext, так и путем задания свойства keyStorePassword. Однако этот способ подбора контейнера имеет некоторые негативные последствия в JCSP, поэтому более правильным кажется загрузка одного заранее известного ключевого контейнера. Это возможно с помощью класса ru.CryptoPro.JCP.KeyStore.StoreInputStream. Класс описан в javadoc-документации дистрибутива КриптоПро JCP. Конструктор класса принимает название контейнера (алиас) в двух форматах: алиас ключа и FQCN-имя контейнера. Например, можно создать SSL-контекст так:

    InputStream container = new StoreInputStream("alias"); // Формируем поток с именем контейнера
    KeyStore keyStore = KeyStore.getInstance(JCSP.HD_STORE_NAME); // Формируем объект для загрузки контейнера
    keyStore.load(container, null); // Загружаем контейнер
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("GostX509"); 
    kmf.init(keyStore, "password".toCharArray()); // Инициализация менеджера ключей 
    SSLContext sslCtx = SSLContext.getInstance("GostTLS"); // Подготовка SSL-контекста 
    sslCtx.init(kmf.getKeyManagers(), ... , null); // Создание SSL-контекста 

либо воспользоваться свойствами keyStore:

    System.setProperty("javax.net.ssl.keyStoreType", "HDIMAGE");
    System.setProperty("javax.net.ssl.keyStore", "alias");

и передать в него алиас контейнера.

При загрузке контейнера с помощью класса StoreInputStream все функции из KeyStore будут возвращать ключ, сертификат и другие данные только из указанного контейнера, за исключением функций типа SetXXX, которые предполагают сохранение контейнера.

Особенностью использования StoreInputStream является также то, что можно получить закрытый ключ, сертификат и т.п. информацию, вызвав getXXX с null вместо алиаса, например:

    InputStream PrivateKey pk = keyStore.getKey(null, "password"); // Получение закрытого ключа
    InputStream Enumeration aliases = keyStore.aliases(); // Получение списка из одного контейнера
    InputStream Certificate cert = keyStore.getCertificate(null); // Получение сертификата

Алиас в этом случае не требуется, т.к. предполагается, что он уже был передан ранее с помощью класса StoreInputStream. Однако данное правило не распространяется на функцию getEntry, т.к. ей запрещено передавать null вместо алиаса.